One of the approaches to improving microprocessor performance is instruction level parallel processing. Instruction level parallel processing involves execution in parallel of low level machine operations, such as memory loads and stores, integer additions and floating point multiplications. Processors for implementing instruction level parallelism typically include multiple execution units and are controlled by very long instruction words (VLIW's). Each VLIW specifies the operations that are to be executed in a single cycle. The source program is typically written in a high level language without attention to operations that can be performed in parallel. The conversion of a source program to machine code which utilizes instruction level parallelism involves scheduling of operations which can be executed in parallel. The scheduling function may be performed by a compiler or by the processor itself. When scheduling is performed by the processor, the processor hardware may become complex. When scheduling is performed by the compiler, the processor simply executes the operations contained in the VLIW. Instruction level parallel processing is described by J. A. Fisher et al in Science, Vol. 253, Sep. 13, 1991, pp. 1233-1241 and by B. Ramakrishna et al in the Journal of Supercomputing, Vol. 7, 1993, pp. 9-50.
For maximum utilization of a processor having multiple execution units, each execution unit should perform an operation as often as possible. The execution units of the processor may be fully utilized during computation-intensive portions of a program, but other portions of the program may not require all the resources of the processor. In this case, instructions that appear later in the program may be scheduled for execution in parallel with earlier instructions, if the operands necessary for execution are available. Because branch instructions are usually present in the program, it may not be possible to determine in advance whether an instruction will require execution. However, if resources of the processor are otherwise idle, the performance of the processor may be improved by executing instructions speculatively, even though execution of those instructions may later be determined to be unnecessary. Execution of an instruction that follows a branch instruction before execution of the branch instruction is known as speculative execution. If the program ultimately requires execution of the instruction that was executed speculatively, an improvement in performance is obtained. If execution of the speculative instruction was not required, the result is discarded.
Speculative execution produces certain effects that must be accounted for in the operation of the processor. For example, if an error condition is generated during execution of the speculative instruction, the error condition should not be reported until a determination is made whether execution of the speculative instruction was required. This avoids processing an error for an instruction which is later discarded. Speculative execution is discussed by M. D. Smith et al in "Efficient Superscalar Performance Through Boosting", ASPLOS V, October, 1992, pp. 248-259; S. A. Mahlke et al, "Sentinel Scheduling for VLIW and Superscalar Processors", ASPLOS V, October, 1992, pp. 238-247 and by A. Rogers et al, "Software Support for Speculative Loads", ASPLOS V, October, 1992, pp. 38-50.
When a processor is connected to I/O devices or to other processors, speculative execution may produce unacceptable external effects. For example, when the processor uses a memory-mapped architecture and an I/O device is mapped to a region of the address space, a speculative memory access operation may accidentally address the region of the address space to which the I/O device is mapped and may cause undesired effects in the I/O device. The undesired effect may be produced simply by accessing a particular address. For example, if the I/O device is a printer, a speculative memory access operation may potentially cause a pen to be activated or an alarm to be sounded. It will be understood that a variety of different effects may be produced. Although execution of the speculative instruction may later be determined to be unnecessary, the effect produced in the I/O device cannot be undone. Thus, such side effects are unacceptable. Addressing of the I/O device by a speculative memory access operation is not intended by the programmer. Instead, such a speculative memory access operation occurs accidentally as a result of the compiler making the operation speculative.